package com.yn.system.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yn.core.base.service.BaseService;
import com.yn.core.exception.ToolBoxException;
import com.yn.core.plugins.dao.Md;
import com.yn.core.toolbox.CMap;
import com.yn.core.toolbox.support.Convert;
import com.yn.system.model.Seqconfig;
import com.yn.system.model.Seqnum;
import com.yn.system.service.SeqconfigService;
import com.yn.system.service.SeqnumService;

/**
 * Generated by.
 * 2017-04-15 22:31:23
 */
@Service
public class SeqnumServiceImpl extends BaseService<Seqnum> implements SeqnumService {
	Logger log=Logger.getLogger(SeqnumServiceImpl.class);
	@Autowired
	SeqconfigService seqconfigService;
	
	@Override
	public boolean updateStatus(String ids, Integer status) {
		CMap map = CMap.init().set("status", status).set("ids", Convert.toIntArray(ids));
		boolean temp = updateBy("status = #{status}", "id in (#{join(ids)})", map);
		return temp;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<String, Object> findOne(Object id) {
		return Md.selectOne("seqnum.findOne", CMap.init().set("id", id), Map.class);
	}

	 /**
     * 获取系统配置编号
     */
    public String generateSystemCode(String tableName, String colName){
        if(tableName==null || "".equals(tableName) || colName==null || "".equals(colName)){
            return null;
        }
        Date date=new Date();
        Seqconfig seqconfig = getSeqConfig(tableName, colName);
        if(seqconfig==null){
            long nowvalue = getSeqNumValue(tableName, colName, null, null, null);
            return String.valueOf(nowvalue);
        }else{
            StringBuilder sysCode=new StringBuilder();
            String prefix=seqconfig.getSeqprefix();
            if(prefix!=null && !"".equals(prefix)){
                sysCode.append(prefix);
            }
            String seqDateformat=seqconfig.getSeqdateformat();
            String dateStr=null;
            if(seqDateformat!=null && !"".equals(seqDateformat)){
                String dateformat = getDateFormat(seqDateformat);
                DateFormat sdf=new SimpleDateFormat(dateformat);
                dateStr=sdf.format(date);
                sysCode.append(dateStr);
            }
            String suffix= seqconfig.getSeqsuffix();
            if(suffix!=null && !"".equals(prefix)){
                sysCode.append(suffix);
            }
            log.debug(sysCode.toString());
            /**获取值当前值**/
            long nowvalue = getSeqNumValue(tableName, colName, seqconfig, seqDateformat, dateStr);
            int seqLength=seqconfig.getSeqlength();
            String nowvalStr=String.valueOf(nowvalue);
            if(seqLength>0){
                if(nowvalStr.length()>seqLength){
                    throw new ToolBoxException("编号生成失败，请调整编号尾数位数！");
                }else{
                    sysCode.append(String.format("%0" + seqLength + "d", nowvalue));
                }
            }else{
                sysCode.append(nowvalue);
            }
            return sysCode.toString();
        }
    }

    private int getSeqNumValue(String tableName, String colName, Seqconfig seqconfig, String seqDateformat, String dateStr){
        List<Seqnum> seqnumList = getSeqnumList(tableName, colName);
        if(seqconfig==null){
            seqconfig=new Seqconfig();
            seqconfig.setSeqinitvalue(10000);
        }
        Integer initValue=seqconfig.getSeqinitvalue();
        int nowvalue=0;
        if(seqnumList!=null && !seqnumList.isEmpty()){
            /***更新已经有的记录***/
            nowvalue = updateSeqNum(seqDateformat, dateStr, seqnumList, initValue);
        }else{
            /**重新插入一条记录**/
            nowvalue = insertSeqNum(tableName, colName, seqDateformat, dateStr, initValue);
        }
        return nowvalue;
    }

    /**
     * 更新一条记录值
     * @param seqDateformat
     * @param dateStr
     * @param seqnumList
     * @param initValue
     * @return
     * @throws Exception
     */
    private int updateSeqNum(String seqDateformat, String dateStr, List<Seqnum> seqnumList, Integer initValue){
        Seqnum seqnum;
        int nowvalue;
        seqnum=seqnumList.get(0);
        if(seqDateformat!=null && !"".equals(seqDateformat)){
            /**但日期规则与现有的日期规则不一致时，生成时间按照新的日期规则来来处理，重新设置日期***/
            if(!seqDateformat.equals(seqnum.getSeqdateformat())){
                nowvalue=initValue;
                seqnum.setSeqdateformat(seqDateformat);
                seqnum.setSeqdate(dateStr);
            }else{
                /**当日期一致时，比较具体的日期是否一样,否则设置初始值**/
                if(!dateStr.equals(seqnum.getSeqdate())){
                    seqnum.setSeqdate(dateStr);
                    nowvalue=initValue;
                }else{
                    nowvalue=seqnum.getSeqnum();
                }
            }
        }else{
            /**当主记录为空时，并且序号表为空时，则表示一致**/
            if(seqnum.getSeqdateformat()==null||"".equals(seqnum.getSeqdateformat())){
                nowvalue=seqnum.getSeqnum();
            }else{
                seqnum.setSeqdateformat(null);
                nowvalue=initValue;
            }
        }
        seqnum.setSeqnum(nowvalue+1);
        this.update(seqnum);
        return nowvalue;
    }

    /**
     * 插入一条序号记录
     * @param orgId
     * @param projectId
     * @param tableName
     * @param colName
     * @param seqDateformat
     * @param dateStr
     * @param initValue
     * @return
     * @throws Exception
     */
    private int insertSeqNum(String tableName, String colName, String seqDateformat, String dateStr, Integer initValue){
        Seqnum seqnum;
        int nowvalue=initValue;
        seqnum=new Seqnum();
        seqnum.setTablename(tableName);
        seqnum.setColname(colName);
        seqnum.setSeqdateformat(seqDateformat);
        seqnum.setSeqdate(dateStr);
        seqnum.setSeqnum(Integer.valueOf(initValue+1));
        this.save(seqnum);
        return nowvalue;
    }

    private List<Seqnum> getSeqnumList(String tableName, String colName){
        StringBuilder sql=new StringBuilder();
        sql.append("select * from YN_SEQNUM where tablename=#{tableName} and colname=#{colName} ");
        sql.append(" and siteid is null");
        CMap cmap=CMap.init().set("tableName", tableName).set("colName", colName);
        List<Seqnum> seqnumList=this.find(sql.toString(), cmap);
        return seqnumList;
    }

    private String getDateFormat(String seqDateformat) {
        String dateformat=seqDateformat;
        if("YYYYMMDD".equals(seqDateformat)){
            dateformat="yyyyMMdd";
        }else if("YYYY-MM-DD".equals(seqDateformat)){
            dateformat="yyyy-MM-dd";
        }else if("YYMMDD".equals(seqDateformat)){
            dateformat="yyMMdd";
        }else if("YY-MM-DD".equals(seqDateformat)){
            dateformat="yy-MM-dd";
        }
        return dateformat;
    }

    private Seqconfig getSeqConfig(String tableName, String colName){
        StringBuilder sql=new StringBuilder();
        sql.append("select * from YN_SEQCONFIG where tablename=#{tableName} and colname=#{colName} ");
        sql.append(" and siteid is null");
        CMap cmap= CMap.init().set("tableName", tableName).set("colName", colName);
        Seqconfig seqconfig=null;
        List<Seqconfig> configList=seqconfigService.find(sql.toString(), cmap);
        if(configList!=null&&!configList.isEmpty()){
            int size=configList.size();
            if(size>2){
                throw new ToolBoxException("错误的编号配置，请联系管理员");
            }else if(size==1){
                seqconfig=configList.get(0);
            }
        }
        return seqconfig;
    }
}
